package com.dongzili.easyes.common.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.dongzili.easyes.common.mybatisplus.PropertyLambdaWrapper;
import com.dongzili.easyes.common.mybatisplus.PropertyQueryWrapper;
import com.dongzili.easyes.custom.entity.SRelationModel;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class QueryWrapperSqlHelper {

    /**
     * 构建查询字段（优先使用 QueryWrapper 中设置的 select，否则查询所有字段）
     */
    private static <T> String buildSelectColumns(QueryWrapper<T> queryWrapper, TableInfo tableInfo) {
        // 若 QueryWrapper 手动设置了 select（如 queryWrapper.select("id", "name")），则使用该字段列表
        if(org.springframework.util.StringUtils.hasText(queryWrapper.getSqlSelect())){
            return queryWrapper.getSqlSelect();
        }
        // 否则查询所有字段（使用 @TableField(value) 配置的列名）
        List<TableFieldInfo> fieldList = tableInfo.getFieldList();
        StringBuilder columns = new StringBuilder();
        for (TableFieldInfo field : fieldList) {
            // 若需强制使用实体类字段名，替换为 field.getProperty()
            columns.append(field.getColumn()).append(", ");
        }
        return columns.substring(0, columns.length() - 2);
    }

    /**
     * 构建 WHERE 条件及排序、分组等子句
     */
    private static <T> String buildWhereClause(QueryWrapper<T> queryWrapper) {
        // 3.5.6 版本中，getCustomSqlSegment() 已包含 WHERE、ORDER BY、GROUP BY 等完整片段
        String sqlSegment = queryWrapper.getCustomSqlSegment();
        return StringUtils.isBlank(sqlSegment) ? "" : " " + sqlSegment;
    }

    /**
     * 填充参数值（处理字符串引号和 SQL 注入防护）
     */
    private static <T> String fillParams(String sql, QueryWrapper<T> queryWrapper) {
        Map<String, Object> paramMap = queryWrapper.getParamNameValuePairs();
        for (Object value : paramMap.values()) {
            if (value == null) {
                sql = sql.replaceFirst("\\?", "NULL");
                continue;
            }
            // 字符串类型加单引号，同时转义内部的单引号（防注入）
            String paramValue = value instanceof String 
                ? "'" + ((String) value).replace("'", "''") + "'" 
                : value.toString();
            sql = sql.replaceFirst("\\?", paramValue);
        }
        return sql;
    }


    /**
     * 根据 QueryWrapper 生成完整 SQL（适配 MP 3.5.6）
     */
    public static <T> String getSql(QueryWrapper<T> queryWrapper, Class<T> entityClass) {
        // 1. 获取实体类对应的表信息（表名、字段映射等）
        TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
        if (tableInfo == null) {
            throw new IllegalArgumentException("实体类未注册：" + entityClass.getName());
        }

        // 2. 构建 SELECT 子句（查询字段，支持 QueryWrapper 中设置的 select 字段）
        String selectColumns = buildSelectColumns(queryWrapper, tableInfo);

        // 3. 构建 FROM 子句（表名）
        String fromClause = "FROM " + tableInfo.getTableName();

        // 4. 构建 WHERE 及排序等条件（从 QueryWrapper 中获取）
        String whereClause = buildWhereClause(queryWrapper);

        // 5. 拼接完整 SQL（含占位符）
        String sql = "SELECT " + selectColumns + " " + fromClause + whereClause;

        // 6. 填充参数值（替换 ? 为实际值）
        return fillParams(sql, queryWrapper);
    }
    public static <T> String getSql(PropertyQueryWrapper<T> queryWrapper, Class<T> entityClass) {
        // 1. 获取实体类对应的表信息（表名、字段映射等）
        TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
        if (tableInfo == null) {
            throw new IllegalArgumentException("实体类未注册：" + entityClass.getName());
        }

        // 2. 构建 SELECT 子句（查询字段，支持 QueryWrapper 中设置的 select 字段）
        String selectColumns = buildSelectColumns(queryWrapper, tableInfo);

        // 3. 构建 FROM 子句（表名）
        String fromClause = "FROM " + tableInfo.getTableName();

        // 4. 构建 WHERE 及排序等条件（从 QueryWrapper 中获取）
        String whereClause = buildWhereClause(queryWrapper);

        // 5. 拼接完整 SQL（含占位符）
        String sql = "SELECT " + selectColumns + " " + fromClause + whereClause;

        // 6. 填充参数值（替换 ? 为实际值）
        return fillParams(sql, queryWrapper);
    }
    private static <T> String buildSelectColumns(PropertyQueryWrapper<T> queryWrapper, TableInfo tableInfo) {
        // 若 QueryWrapper 手动设置了 select（如 queryWrapper.select("id", "name")），则使用该字段列表
        if(org.springframework.util.StringUtils.hasText(queryWrapper.getSqlSelect())){
            return queryWrapper.getSqlSelect();
        }
        // 否则查询所有字段（使用 @TableField(value) 配置的列名）
        List<TableFieldInfo> fieldList = tableInfo.getFieldList();
        StringBuilder columns = new StringBuilder();
        for (TableFieldInfo field : fieldList) {
            // 若需强制使用实体类字段名，替换为 field.getProperty()
            columns.append(field.getColumn()).append(", ");
        }
        return columns.substring(0, columns.length() - 2);
    }
    private static <T> String buildWhereClause(PropertyQueryWrapper<T> queryWrapper) {
        // 3.5.6 版本中，getCustomSqlSegment() 已包含 WHERE、ORDER BY、GROUP BY 等完整片段
        String sqlSegment = queryWrapper.getCustomSqlSegment();
        return StringUtils.isBlank(sqlSegment) ? "" : " " + sqlSegment;
    }
    private static <T> String fillParams(String sql, PropertyQueryWrapper<T> queryWrapper) {
        Map<String, Object> paramMap = queryWrapper.getParamNameValuePairs();
        for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
            String key = String.format("#{ew.paramNameValuePairs.%s}", entry.getKey());
            if (entry.getValue() == null) {
                sql = sql.replace(key, "NULL");
                continue;
            }

            if (sql.contains(key)){
                if (entry.getValue() instanceof String){
                    sql = sql.replace(key, "'" + entry.getValue() + "'");
                }else{
                    sql = sql.replace(key, String.valueOf(entry.getValue()));
                }
            }

        }

//        for (Object value : paramMap.values()) {
//            if (value == null) {
//                sql = sql.replaceFirst("\\?", "NULL");
//                continue;
//            }
//            // 字符串类型加单引号，同时转义内部的单引号（防注入）
//            String paramValue = value instanceof String
//                    ? "'" + ((String) value).replace("'", "''") + "'"
//                    : value.toString();
//            sql = sql.replaceFirst("\\?", paramValue);
//        }
        return sql;
    }


    public static void main(String[] args) {
        PropertyQueryWrapper<SRelationModel> wrapper = new PropertyQueryWrapper<>();
        PropertyLambdaWrapper<SRelationModel> lambdaWrapper = wrapper.lambda();
        lambdaWrapper.eq(SRelationModel::getFlag, 0);
        lambdaWrapper.gt(SRelationModel::getTermID, 0);
        lambdaWrapper.groupBy(SRelationModel::getTermID, SRelationModel::getTermName,SRelationModel::getLibraryID, SRelationModel::getLibraryName);
//        lambdaWrapper.select("count(distinct resCode) as count",SRelationModel::getTermID, SRelationModel::getTermName,SRelationModel::getLibraryID, SRelationModel::getLibraryName);
        lambdaWrapper.select(Arrays.asList(SRelationModel::getTermID, SRelationModel::getTermName,SRelationModel::getLibraryID, SRelationModel::getLibraryName),"count(distinct resCode) as count");

        System.out.println(getSql(wrapper, SRelationModel.class));
    }
}